package ma.meditel.reporting.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import ma.meditel.reporting.entities.Traffic;
import ma.meditel.reporting.entities.TrafficClassification;

public class TrafficsHelper {
	
	public static Traffic isListTrafficsContaineDate(List<Traffic> traffics, Date date){
		for(Traffic t : traffics){
			if(t.getDate().compareTo(date) == 0){
				return t;
			}
		}
		
		return null;
	}
	
	public static TrafficClassification isListTrafficsPerClassContaineDate(List<TrafficClassification> traffics, Date date){
		for(TrafficClassification t : traffics){
			if(t.getDate().compareTo(date) == 0){
				return t;
			}
		}
		
		return null;
	}
	//AVG banaya style
	public static List<Double> TrafficsToAVG(List<Double> data, int margeAgregation){
		List<Double> finalDataset = new ArrayList<>();
		double sum = 0;
		int divBy = margeAgregation/5;
		
		int minute = 0;
		
		for(Double d : data){
			if(minute % margeAgregation != 0){
				sum += d;
				
			}else {
				sum += d;
				sum /= divBy;
				
				if(minute == 0)//First value
					finalDataset.add(d);
				else
					finalDataset.add(sum);
				
				sum = 0;
			}
			minute += 5;
		}
		return finalDataset;
	}
	
	private static Double avgOfTrafficsValues(Double trafficsTotalValue, int count)
	{
		return trafficsTotalValue/(double) count;
	}
	
	//AVG New
		public static List<Double> TrafficsToAVG_New(List<Traffic> theList_){
			List<Double> finalDataset = new ArrayList<>();
			List<Traffic> theNewListOfTraffics = new ArrayList<Traffic>();
			int count = 0;
			int i = 0;
			Double trafficsTotalValue = (double) 0;
			int theCourrentHour = 0;
			Date tempDate,theTempDateBegin, theTempDateEnd;
			Boolean passe = false;
			
			theTempDateBegin = theList_.get(0).getDate();
			theTempDateEnd = new Date(theTempDateBegin.getTime() + (long) (3600*1000));
			
			for(Traffic t : theList_)
			{
				
				if(t.getDate().compareTo(theTempDateBegin) >= 0 &&  t.getDate().compareTo(theTempDateEnd) < 0)
				{
					System.out.println("c1 : "+t.getDate().compareTo(theTempDateBegin)+"\tc2 : "+t.getDate().compareTo(theTempDateEnd));
					System.out.println("i = "+i+"\tdate traffic :"+t.getDate()+"\tvalue : "+t.getCalculatedMetriceValue());
					trafficsTotalValue += t.getMetriceValue();
					if(count == 0 || (count == 1 && i!=0))
					{	
						theNewListOfTraffics.add(t);
						tempDate = t.getDate();
						tempDate.setMinutes(0);tempDate.setSeconds(0);
						theNewListOfTraffics.get(i).setDate(tempDate);
						theNewListOfTraffics.get(i).setMetriceValue((double) 0);
						passe = true;
					}
					count++;
//					System.out.println("theCourrentHour : " + theCourrentHour + "\tcount : "+count +"\ttrafficsTotalValue : "+trafficsTotalValue);
				}
				else
				{	
//					System.out.println("before the avg count =  " + count+"\t i = "+i);
					if(passe){
						theNewListOfTraffics.get(i).setMetriceValue(avgOfTrafficsValues(trafficsTotalValue,count));
						
						
						trafficsTotalValue = (double) 0;
						count=0;
						i++;
						theTempDateBegin = new Date(theTempDateBegin.getTime() + (long) (3600*1000));
						theTempDateEnd = new Date(theTempDateBegin.getTime() + (long) (3600*1000));
						
						
						
						trafficsTotalValue += t.getMetriceValue();
						count++;
						passe = false;
					}
						
					
				}
			}
			if(i != 0 && passe) theNewListOfTraffics.get(i).setMetriceValue(avgOfTrafficsValues(trafficsTotalValue,count));
			
			int c = 0;
			for(Traffic t : theNewListOfTraffics)
			{
				c++;
				System.out.println("c = "+c+"\tdate traffic :"+t.getDate()+"\tvalue : "+t.getCalculatedMetriceValue());
				finalDataset.add(t.getCalculatedMetriceValue());
			}

			return finalDataset;
		}
	
		
		//AVG New
		public static List<Double> TrafficsToAVG_NewForDay(List<Traffic> theList_){
			
			Date starIterationtDate = new Date(theList_.get(0).getDate().getTime());
			Date endIterationDate = new Date(starIterationtDate.getTime() + (3600*1000*24));
			List<Traffic> newListOfTraffic = new ArrayList<Traffic>();
			
			while(starIterationtDate.compareTo(theList_.get(0).getDate()) >= 0 && 
					starIterationtDate.compareTo(theList_.get(theList_.size()-1).getDate()) <= 0 )
			{
				newListOfTraffic.add(getTheAvgOfValueBetwen(starIterationtDate, endIterationDate, theList_));
				starIterationtDate.setTime(starIterationtDate.getTime() + (3600*1000*24));
				endIterationDate.setTime(endIterationDate.getTime() + (3600*1000*24));
			}
			List<Double> finalDataset = new ArrayList<>();
			
			for(Traffic t : newListOfTraffic)
			{
				finalDataset.add(t.getCalculatedMetriceValue());
			}
			
			return finalDataset;
		}
		
		public static List<Double> newTrafficsToAVG_(List<Traffic> theList_, int marge, Date dateDebut){
			
			Date starIterationtDate = new Date(dateDebut.getTime());
			
			System.out.println("la date est : "+starIterationtDate);
			Date endIterationDate = new Date(starIterationtDate.getTime() + (60*1000*marge));
			List<Traffic> newListOfTraffic = new ArrayList<Traffic>();
			
			
			while(starIterationtDate.compareTo(theList_.get(theList_.size()-1).getDate()) <= 0 )
			{
				System.out.println("la date est : "+starIterationtDate);
				newListOfTraffic.add(getTheAvgOfValueBetwen(starIterationtDate, endIterationDate, theList_));
				starIterationtDate.setTime(starIterationtDate.getTime() + (60*1000*marge));
				endIterationDate.setTime(endIterationDate.getTime() + (60*1000*marge));
			}
			List<Double> finalDataset = new ArrayList<>();
			
			System.out.println("size_ : "+newListOfTraffic.size());
			
			for(Traffic t : newListOfTraffic)
			{
				finalDataset.add(t.getCalculatedMetriceValue());
			}
			
			return finalDataset;
		}
		
		private static Traffic getTheAvgOfValueBetwen(Date debut, Date fin,List<Traffic> theList_)
		{
			System.out.println("dDebut: " + debut + " dFin: " + fin);
			int count = 0, i = 0;
			Traffic theNewListOfTraffic = new Traffic();
			Double trafficsTotalValue = (double) 0;
			Boolean passe = false;
			Date tempDate = new Date();
			
			theNewListOfTraffic.setDate(debut);
			theNewListOfTraffic.setMetriceValue((double) 0); 
			for(Traffic t : theList_)
			{
				if(t.getDate().compareTo(debut) >= 0 &&  t.getDate().compareTo(fin) < 0)
				{
					trafficsTotalValue += t.getMetriceValue();
					if(count == 0)
					{	
						theNewListOfTraffic = new Traffic(t);
						theNewListOfTraffic.setMetriceValue((double) 0);
						passe = true;
					}
					count++;
				}else
				{
					if(passe && count != 0) break;
				}
			}
			
			if(passe) theNewListOfTraffic.setMetriceValue(avgOfTrafficsValues(trafficsTotalValue,count));
			
			return theNewListOfTraffic;
		}
		
		
	//MAX
	public static List<Double> TrafficsToMAX(List<Double> data, int margeAgregation){
		List<Double> finalDataset = new ArrayList<>();
		Double max = null;
		int minute = 0;
		
		for(Double d : data){
			if(max == null || d > max){
				max = d;
			}
			
			if(minute % margeAgregation == 0){
				finalDataset.add(max);
				max = null;
			}
			minute += 5;
		}
		return finalDataset;
	}
	
	//MIN
	public static List<Double> TrafficsToMIN(List<Double> data, int margeAgregation){
		List<Double> finalDataset = new ArrayList<>();
		Double min = null;
		int minute = 0;
		
		for(Double d : data){
			if(min == null || d < min){
				min = d;
			}
			
			if(minute % margeAgregation == 0){
				finalDataset.add(min);
				min = null;
			}
			minute += 5;
		}
		return finalDataset;
	}	
	
	//REEL
	public static List<Double> TrafficsToREEL(List<Double> data, int margeAgregation){
		List<Double> finalDataset = new ArrayList<>();
		int minute = 0;
		
		for(Double d : data){
			if(minute % margeAgregation == 0){
				finalDataset.add(d);
			}
			minute += 5;
		}
		return finalDataset;
	}

	
	
	
	public static List<Double> newTrafficsToMin_(List<Traffic> theList_, int marge, Date dateDebut)
	{
		
		Date starIterationtDate = new Date(dateDebut.getTime());
		Date endIterationDate = new Date(starIterationtDate.getTime() + (60*1000*marge));
		List<Traffic> newListOfTraffic = new ArrayList<Traffic>();
		
		while(starIterationtDate.compareTo(theList_.get(theList_.size()-1).getDate()) <= 0 )
		{
			newListOfTraffic.add(getTheAvgOfValueBetwenMin(starIterationtDate, endIterationDate, theList_));
			starIterationtDate.setTime(starIterationtDate.getTime() + (60*1000*marge));
			endIterationDate.setTime(endIterationDate.getTime() + (60*1000*marge));
		}
		List<Double> finalDataset = new ArrayList<>();
		
		for(Traffic t : newListOfTraffic)
		{
			finalDataset.add(t.getCalculatedMetriceValue());
		}
		
		return finalDataset;
	}
	
	
	private static Traffic getTheAvgOfValueBetwenMin(Date debut, Date fin,List<Traffic> theList_)
	{
		int count = 0, i = 0;
		Traffic theNewListOfTraffic = new Traffic();
		double trafficsMaxValue = (double) 0;
		
		Boolean passe = false;
		Date tempDate = new Date();
		
		theNewListOfTraffic.setDate(debut);
		theNewListOfTraffic.setMetriceValue((double) 0); 
		for(Traffic t : theList_)
		{
			
			if(t.getDate().compareTo(debut) >= 0 &&  t.getDate().compareTo(fin) < 0)
			{	if(count == 0) trafficsMaxValue = t.getMetriceValue();
				if(trafficsMaxValue > t.getMetriceValue()) trafficsMaxValue = t.getMetriceValue();
				passe = true;
				count++;
			}else
			{
				if(passe && count != 0) break;
			}
		}
		
		if(passe) theNewListOfTraffic.setMetriceValue(trafficsMaxValue);
		
		return theNewListOfTraffic;
	}
	
	
	
	public static List<Double> newTrafficsToMax_(List<Traffic> theList_, int marge, Date dateDebut)
	{
		
		Date starIterationtDate = new Date(dateDebut.getTime());
		Date endIterationDate = new Date(starIterationtDate.getTime() + (60*1000*marge));
		List<Traffic> newListOfTraffic = new ArrayList<Traffic>();
		
		while(starIterationtDate.compareTo(theList_.get(theList_.size()-1).getDate()) <= 0 )
		{
			newListOfTraffic.add(getTheAvgOfValueBetwenMax(starIterationtDate, endIterationDate, theList_));
			starIterationtDate.setTime(starIterationtDate.getTime() + (60*1000*marge));
			endIterationDate.setTime(endIterationDate.getTime() + (60*1000*marge));
		}
		List<Double> finalDataset = new ArrayList<>();
		
		for(Traffic t : newListOfTraffic)
		{
			finalDataset.add(t.getCalculatedMetriceValue());
		}
		
		return finalDataset;
	}
	
	
	private static Traffic getTheAvgOfValueBetwenMax(Date debut, Date fin,List<Traffic> theList_)
	{
		int count = 0, i = 0;
		Traffic theNewListOfTraffic = new Traffic();
		Double trafficsMaxValue = (double) 0;
		Boolean passe = false;
		Date tempDate = new Date();
		
		theNewListOfTraffic.setDate(debut);
		theNewListOfTraffic.setMetriceValue((double) 0); 
		for(Traffic t : theList_)
		{
			if(t.getDate().compareTo(debut) >= 0 &&  t.getDate().compareTo(fin) < 0)
			{
				if(trafficsMaxValue < t.getMetriceValue()) trafficsMaxValue = t.getMetriceValue();
				passe = true;
				count++;
			}else
			{
				if(passe && count != 0) break;
			}
		}
		
		if(passe) theNewListOfTraffic.setMetriceValue(trafficsMaxValue);
		
		return theNewListOfTraffic;
	}
}
